home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / smaltalk.lha / smalltalk-1.1.1 / Metaclass.st < prev    next >
Text File  |  1991-09-12  |  9KB  |  277 lines

  1. "======================================================================
  2. |
  3. |   MetaClass Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbyrne     16 May 90      Changed the implementation of name: ... to try to
  34. |              preserve an existing class (if possible).  The
  35. |              original code exists in newMeta: ...
  36. |
  37. | sbyrne     25 Apr 89      created.
  38. |
  39. "
  40.  
  41. ClassDescription subclass: #Metaclass
  42.          instanceVariableNames: 'instanceClass'
  43.          classVariableNames: ''
  44.          poolDictionaries: ''
  45.          category: nil !
  46.  
  47. Metaclass comment: 
  48. 'I am the root of the class hierarchy.  My instances are metaclasses, one for
  49. each real class.  My instances have a single instance, which they hold
  50. onto, which is the class that they are the metaclass of.  I provide methods
  51. for creation of actual class objects from metaclass object, and the creation
  52. of metaclass objects, which are my instances.  If this is confusing to you,
  53. it should be...the Smalltalk metaclass system is strange and complex.' !
  54.  
  55. !Metaclass class methodsFor: 'instance creation'!
  56.  
  57. subclassOf: superMeta
  58.     | newMeta |
  59.     newMeta _ self new.
  60.     newMeta superclass: superMeta.
  61.     superMeta addSubclass: newMeta.
  62.     newMeta initMetaclass.
  63.     ^newMeta
  64.  
  65. !!
  66.  
  67.  
  68.  
  69. !Metaclass methodsFor: 'basic'!
  70.  
  71. name: newName
  72.     environment: aSystemDictionary
  73.     subclassOf: superclass
  74.     instanceVariableNames: stringOfInstVarNames
  75.     variable: variableBoolean
  76.     words: wordBoolean
  77.     pointers: pointerBoolean
  78.     classVariableNames: stringOfClassVarNames
  79.     poolDictionaries: stringOfPoolNames
  80.     category: categoryName
  81.     comment: commentString
  82.     changed: changed
  83.     | aClass variableString variableArray sharedPoolNames poolName pool 
  84.       className classVarDict oldClassPool |
  85.  
  86.     "Please don't look at this case for an example of how to create good 
  87.      Smalltalk code.  It is inelegantly written and probably highly 
  88.     inefficient."
  89.  
  90.     className _ newName asSymbol.
  91.     aClass _ aSystemDictionary 
  92.     at: className
  93.     ifAbsent: [ ^self newMeta: newName
  94.               environment: aSystemDictionary
  95.               subclassOf: superclass
  96.               instanceVariableNames: stringOfInstVarNames
  97.               variable: variableBoolean
  98.               words: wordBoolean
  99.               pointers: pointerBoolean
  100.               classVariableNames: stringOfClassVarNames
  101.               poolDictionaries: stringOfPoolNames
  102.               category: categoryName
  103.               comment: commentString
  104.               changed: changed ].
  105.  
  106.     (aClass isVariable == variableBoolean)
  107.     & (aClass isWords == wordBoolean )
  108.     & (aClass isPointers == pointerBoolean)
  109.     ifFalse: [ ^self newMeta: newName
  110.               environment: aSystemDictionary
  111.               subclassOf: superclass
  112.               instanceVariableNames: stringOfInstVarNames
  113.               variable: variableBoolean
  114.               words: wordBoolean
  115.               pointers: pointerBoolean
  116.               classVariableNames: stringOfClassVarNames
  117.               poolDictionaries: stringOfPoolNames
  118.               category: categoryName
  119.               comment: commentString
  120.               changed: changed ].
  121.  
  122.     "Here we have an existing class, so try hard to leave it alone"
  123.     instanceClass _ aClass.
  124.     aClass setSuperclass: superclass.
  125.  
  126.     superclass notNil
  127.         ifTrue: [ "Inherit instance variables from parent"
  128.               variableString _ superclass instanceVariableString
  129.           ]
  130.         ifFalse: [ variableString _ '' ].
  131.     variableString _ variableString , stringOfInstVarNames.
  132.     variableArray _ self parseVariableString: variableString.
  133.     1 to: variableArray size do:
  134.         [ :i | variableArray at: i put: (variableArray at: i) asSymbol ].
  135.     variableArray = aClass instVarNames
  136.     ifFalse: [ 'Recompilation required!' printNl.
  137.            "### This should be fixed soon" ].
  138.     aClass setInstanceVariables: variableArray.
  139.  
  140.     aClass setInstanceSpec: variableBoolean words: wordBoolean
  141.         pointers: pointerBoolean instVars: variableArray size.
  142.  
  143.     classVarDict _ (self parseToDict: stringOfClassVarNames).
  144.     oldClassPool _ aClass classPool.
  145.     oldClassPool isNil 
  146.     ifTrue: [ aClass setClassVariables: classVarDict ]
  147.     ifFalse: [ classVarDict associationsDo:
  148.                [ :assoc | (oldClassPool includesKey: assoc key)
  149.                       ifFalse: 
  150.                       [ aClass addClassVarName: 
  151.                         assoc key ] ] ].
  152.     classVarDict keys  ~= aClass classPool keys
  153.     ifTrue: [ 'Recompilation required: different class variables!' 
  154.                       printNl ].
  155.  
  156.     sharedPoolNames _ self parseVariableString: stringOfPoolNames.
  157.     1 to: sharedPoolNames size do:
  158.         [ :i | poolName _ (sharedPoolNames at: i) asSymbol.
  159.                "### Check that the pool name starts with an uppercase letter
  160.         here."
  161.            "??? Should this create the pool if not there?"
  162.            pool _ aSystemDictionary
  163.                        at: poolName
  164.                        ifAbsent: [ ^self error: 'Pool name ', poolName ,
  165.                                      ' does not exist' ].
  166.               sharedPoolNames at: i put: pool ].
  167.     "### probably should check for recompilation required here in case
  168.      the intersection of the sets of pool dictionaries shrinks"
  169.     aClass setSharedPools: sharedPoolNames.
  170.  
  171.     "### not done"
  172.     aClass category: categoryName. "### need to remove the old category maybe"
  173.     "### don't know what to do with changed"
  174.     ^aClass
  175. !
  176.  
  177.  
  178. newMeta: newName
  179.     environment: aSystemDictionary
  180.     subclassOf: superclass
  181.     instanceVariableNames: stringOfInstVarNames
  182.     variable: variableBoolean
  183.     words: wordBoolean
  184.     pointers: pointerBoolean
  185.     classVariableNames: stringOfClassVarNames
  186.     poolDictionaries: stringOfPoolNames
  187.     category: categoryName
  188.     comment: commentString
  189.     changed: changed
  190.     | aClass variableString variableArray sharedPoolNames poolName pool |
  191.  
  192.     sharedPoolNames _ self parseVariableString: stringOfPoolNames.
  193.     1 to: sharedPoolNames size do:
  194.         [ :i | poolName _ (sharedPoolNames at: i) asSymbol.
  195.                "### Check that the pool name starts with an uppercase letter
  196.         here."
  197.            pool _ aSystemDictionary
  198.                        at: poolName
  199.                        ifAbsent: [ ^self error: 'Pool name ', poolName ,
  200.                                      ' does not exist' ].
  201.               sharedPoolNames at: i put: pool ].
  202.     aClass _ self new.
  203.     instanceClass _ aClass.
  204.     aSystemDictionary at: (newName asSymbol) put: aClass.
  205.     aClass superclass: superclass.
  206.     aClass setName: newName asSymbol.
  207.     superclass notNil
  208.         ifTrue: [ superclass addSubclass: aClass.
  209.                   "Inherit instance variables from parent"
  210.               variableString _ superclass instanceVariableString
  211.           ]
  212.         ifFalse: [ variableString _ '' ].
  213.     variableString _ variableString , stringOfInstVarNames.
  214.     variableArray _ self parseVariableString: variableString.
  215.     1 to: variableArray size do:
  216.         [ :i | variableArray at: i put: (variableArray at: i) asSymbol ].
  217.     aClass setInstanceVariables: variableArray.
  218.     aClass setInstanceSpec: variableBoolean words: wordBoolean
  219.         pointers: pointerBoolean instVars: variableArray size.
  220.     aClass setClassVariables: (self parseToDict: stringOfClassVarNames).
  221.     aClass setSharedPools: sharedPoolNames.
  222.     "### not done"
  223.     aClass category: categoryName.
  224.     aClass comment: commentString.
  225.     "### don't know what to do with changed"
  226.     ^aClass
  227. !!
  228.  
  229.  
  230.  
  231. !Metaclass methodsFor: 'accessing'!
  232.  
  233. instanceClass
  234.     ^instanceClass
  235. !!
  236.  
  237.  
  238.  
  239.  
  240. !Metaclass methodsFor: 'printing'!
  241.  
  242. printOn: aStream
  243.     instanceClass printOn: aStream.
  244.     ' class' printOn: aStream
  245. !
  246.  
  247. storeOn: aStream
  248.     self printOn: aStream
  249. !!
  250.  
  251.  
  252.  
  253. !Metaclass methodsFor: 'private'!
  254.  
  255. initMetaclass
  256.     instanceVariables _ Class instVarNames.
  257.     instanceSpec _ Class instanceSpec
  258. !
  259.  
  260. parseVariableString: aString
  261.     | stream |
  262.     stream _ TokenStream on: aString.
  263.     ^stream contents
  264. !
  265.  
  266. parseToDict: aString
  267.     | tokenArray dict |
  268.     tokenArray _ self parseVariableString: aString.
  269.     dict _ Dictionary new.
  270.     tokenArray do:
  271.         [ :element | dict at: element asSymbol put: nil ].
  272.     ^dict
  273.  
  274. !!
  275.